using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Data;


namespace sCicero
{
    public class Tree : Base
    {
        private const string TREE = "tree";

        public Tree(ref Data oData)
        {
            m_Table = TREE;
            m_oData = oData;
        }
        public Errorcode New(string sName, int nParentId)
        {
            DataRow o_Dr = m_oData.GetGenericDataTable(TREE).NewRow();
            o_Dr["name"] = sName;
            if (m_oData.GetGenericDataTable(TREE).Rows.Count > 0)
                o_Dr["parent_id"] = nParentId;
            m_oData.GetGenericDataTable(TREE).Rows.Add(o_Dr);
            m_oData.AcceptChanges(TREE);
            return Errorcode.NOERROR;
        }
        public Errorcode New(string sName)
        {
            DataRow o_Dr = m_oData.GetGenericDataTable(TREE).NewRow();
            o_Dr["name"] = sName;
            m_oData.GetGenericDataTable(TREE).Rows.Add(o_Dr);
            m_oData.AcceptChanges(TREE);
            return Errorcode.NOERROR;
        }
        public Errorcode MoveTest(int nTreeId, int nTestId)
        {
            foreach(DataRow oDr in m_oData.GetGenericDataTable("treelink_test").Select("test_id = " + nTestId))
            {
                oDr.Delete();
            }
            DataRow o_Dr = m_oData.GetGenericDataTable("treelink_test").NewRow();
            o_Dr["test_id"] = nTestId;
            o_Dr["tree_id"] = nTreeId;
            m_oData.GetGenericDataTable("treelink_test").Rows.Add(o_Dr);
            m_oData.AcceptChanges("treelink_test");
            return Errorcode.NOERROR;
        }

        private void AddNode(ref XmlTextWriter oXMLWriter, int nTreeId, ref int nNodesCount)
        {
            nNodesCount++;
            oXMLWriter.WriteStartElement("node");
            oXMLWriter.WriteElementString("name", m_oData.GetGenericDataTable(TREE).Rows.Find(nTreeId)["name"].ToString());
            oXMLWriter.WriteElementString("tree_id", nTreeId.ToString());

            foreach (DataRow oDr_items in m_oData.GetGenericDataTable("treelink_test").Select("tree_id = " + nTreeId.ToString()))
            {
                oXMLWriter.WriteStartElement("item");
                oXMLWriter.WriteElementString("test_name", m_oData.GetGenericDataTable("tests").Rows.Find(oDr_items["test_id"])["name"].ToString());
                oXMLWriter.WriteElementString("test_id", oDr_items["test_id"].ToString());
                oXMLWriter.WriteEndElement();
            }

            if (m_oData.GetGenericDataTable(TREE).Select("parent_id = " + nTreeId.ToString()).Length > 0)
            {
                foreach (DataRow oDr in m_oData.GetGenericDataTable(TREE).Select("parent_id = " + nTreeId.ToString()))
                {
                    AddNode(ref oXMLWriter, int.Parse(oDr["id"].ToString()), ref nNodesCount);
                }
            }
            //add the end node of "node"
            oXMLWriter.WriteEndElement();
        }

        public XmlDocument GetTree()
        {
            m_LastError = "";
            m_LastReturnCode = Errorcode.NOERROR;
            try
            {
                m_oData.TableName = m_Table;
                System.IO.FileStream oStream = new System.IO.FileStream("temp.xml", System.IO.FileMode.Create);
                System.Xml.XmlTextWriter oXMLWriter = new System.Xml.XmlTextWriter(oStream, Encoding.GetEncoding("iso-8859-1"));

                oXMLWriter.WriteStartDocument();
                oXMLWriter.WriteStartElement("scicero");
                oXMLWriter.WriteStartElement("root");
                int nNodesCount = 0;
                //get starting node
                if (m_oData.GetGenericDataTable(TREE) != null && m_oData.GetGenericDataTable(TREE).Rows.Count > 0)
                {
                    //int nTreeId = int.Parse(m_oData.GetGenericDataTable(TREE).Select("parent_id is null")[0]["id"].ToString());
                    //add the test thats not in a node
                    foreach (DataRow oDr in m_oData.GetGenericDataTable("tests").Rows)
                    {
                        if (m_oData.GetGenericDataTable("treelink_test").Select("test_id = " + oDr["id"].ToString()).Length == 0)
                        {
                            oXMLWriter.WriteStartElement("item");
                            oXMLWriter.WriteElementString("test_name", oDr["name"].ToString());
                            oXMLWriter.WriteElementString("test_id", oDr["id"].ToString());
                            oXMLWriter.WriteEndElement();
                        }
                    }
                    foreach (DataRow oDr in m_oData.GetGenericDataTable(TREE).Select("parent_id is null"))
                    {
                        AddNode(ref oXMLWriter, int.Parse(oDr["id"].ToString()), ref nNodesCount);
                    }
                }
                if (nNodesCount == 0)
                {
                    //nothing found, add all the test to this root node
                    foreach (DataRow oDr in m_oData.GetGenericData("tests"))
                    {
                        oXMLWriter.WriteStartElement("item");
                        oXMLWriter.WriteElementString("test_name", oDr["name"].ToString());
                        oXMLWriter.WriteElementString("test_id", oDr["id"].ToString());
                        oXMLWriter.WriteEndElement();
                    }

                }
                oXMLWriter.WriteEndElement(); //root
                oXMLWriter.WriteEndElement(); //scicero 
                oXMLWriter.WriteEndDocument();

                oXMLWriter.Flush();

                System.Xml.XmlDocument oXMLDoc = new System.Xml.XmlDocument();
                oStream.Position = 0;
                oXMLDoc.Load(oStream);
                oXMLWriter.Close();
                return oXMLDoc;
            }
            catch (Exception ex)
            {
                m_LastError = "GetTree Error: " + ex.Message;
                m_LastReturnCode = Errorcode.GENERAL_ERROR;
                return null;
            }

        }
    }
}
